/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package SPARQL.Utilities;

import Rewriting.VariableNameGenerator;
import SPARQL.Binding;
import SPARQL.SPARQL;
import SPARQL.Term;
import SPARQL.TriplePattern;
import SPARQL.Variable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.script.Bindings;

/**
 *
 * @author dimartinomirko
 */



public abstract class SPARQLVariableRenamer {
    
    protected Map<Variable, Variable> varsMap;
    

    public SPARQLVariableRenamer(){
    this.varsMap = new HashMap<Variable, Variable>();
   
    
    }

    public abstract void renameVariables();
     
     
    /*
    questo metodo rinomina solo le variabili nel body delle query dei mapping e non quelle nella SELECT
    non e' un rename completo serve solo a fare funzionare il rewriting
    */
    
    
        protected void renameListTerms(List<Term> setTerms) {
            
           
            
            for (Term term : setTerms){
                if (term instanceof Variable){
                    Variable var = (Variable) term;
                    var.setVar(getRespectiveNewVariable((Variable) term).getVar());
                }
            }
            
        }
       
        
    
    
    protected void renameTriple(TriplePattern triple){
        if (triple.getS() instanceof Variable){
            
            Variable var = (Variable) triple.getS();
        
            triple.setS(getRespectiveNewVariable(var));
        }
        if (triple.getP() instanceof Variable){
            
            Variable var = (Variable) triple.getP();
        
            triple.setP(getRespectiveNewVariable(var));
        }
        if (triple.getO() instanceof Variable){
            
            Variable var = (Variable) triple.getO();
        
            triple.setO(getRespectiveNewVariable(var));
        }
        
        
    }
    
    protected Variable getRespectiveNewVariable (Variable var){
        if (!this.varsMap.containsKey(var)){
            VariableNameGenerator generator = VariableNameGenerator.getInstance();
            Variable newVar = new Variable(generator.newVariable());
            this.varsMap.put(var, newVar);
            
            
        }
        return this.varsMap.get(var);
        
    }
    
    protected void renameSetTriples(Set<TriplePattern> tripleSet){
        Set<TriplePattern> iterationSet = new HashSet<TriplePattern>();
        for (TriplePattern triple : tripleSet){
        iterationSet.add((TriplePattern) triple.clone());
                }
        
     for (TriplePattern triple : iterationSet) {
         tripleSet.remove(triple);
         renameTriple(triple);
         tripleSet.add(triple);
     }     
    }
    
    protected void renameBindings(List<Binding> bindings) {
        for (Binding binding : bindings){
            if (binding.getTerm1() instanceof Variable) 
                binding.setTerm1(getRespectiveNewVariable((Variable) binding.getTerm1()));
            if (binding.getTerm2() instanceof Variable) 
                binding.setTerm2(getRespectiveNewVariable((Variable) binding.getTerm2()));
        }
    }

    
    
    
}
